import json
import re
from django.contrib.auth import login
from django.contrib.auth import logout
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from apps.users.models import User



# Create your views here.
# 用户名和密码 AJAX 检查
class UsernameCountView(View):
    # 用户名验证
    def get(self,request,username):
        # rules = '[a-zA-Z0-9]{5,20}'
        # if not re.match(rules,username):
        #     return JsonResponse({'code':0,'errmsg':'用户名格式错误'})
        count = User.objects.filter(username=username).count()
        return JsonResponse({'code':0,'count':count,'errmsg':'ok'})

class MobileCountView(View):
    # 手机号验证
    def get(self,request,mobile):
        count = User.objects.filter(mobile=mobile).count()
        return JsonResponse({'code':0,'count':count,'errmsg':'ok'})

# 注册
class RegisterView(View):
    def post(self,request):
        body_bytes = request.body
        body_dict = json.loads(body_bytes)
        print(type(body_dict),body_dict)

        username= body_dict.get('username')
        password= body_dict.get('password')
        password2= body_dict.get('password2')
        mobile = body_dict.get('mobile')
        image_code= body_dict.get('image_code')
        sms_code= body_dict.get('sms_code')
        allow= body_dict.get('allow')

        if not all([username,password,mobile]):
            return JsonResponse({'code':400,'errmsg':'缺少必要信息'})
        if not re.match(r'^[a-zA-Z0-9]{5,20}$',username):
            return JsonResponse({'code':400,'errmsg':'用户名格式错误'})
        if not re.match(r'^[a-zA-Z0-9_]{8,20}$',password):
            return JsonResponse({'code': 400, 'errmsg': '密码格式错误'})
        if password != password2:
            return JsonResponse({'code': 400, 'errmsg': '两次密码不一致'})
        if not re.match(r'^1[3-9]\d{9}$',mobile):
            return JsonResponse({'code': 400, 'errmsg': '手机号格式错误'})
        if allow != True:
            return JsonResponse({'code': 400, 'errmsg': '未勾选同意协议'})
        # 验证码验证
        from django_redis import get_redis_connection
        redis_cli = get_redis_connection('code')
        redis_code = redis_cli.get(mobile).decode()
        if redis_code is None:
            return JsonResponse({'code': 400, 'errmsg': '短信验证码失效'})
        if redis_code != sms_code:
            return JsonResponse({'code':400,'errmsg':'验证码错误'})

        # 保存的密码没有加密
        # User.objects.create(username = username,password = password,mobile = mobile)
        # 保存的密码加密
        try:
            user = User.objects.create_user(
                username = username,
                password = password,
                mobile = mobile
            )
        except Exception as e:
            print(e)
            return JsonResponse({'code': 400, 'errmsg': '注册失败'})

        # 保存账号,用户自动登录
        login(request,user)

        response = JsonResponse({'code':0,'errmsg':'ok'})
        response.set_cookie('username',username,max_age=3600 * 24 * 15)
        return response

# 登录
class LoginView(View):
    def post(self,request):
        data = json.loads(request.body)
        username = data.get('username')
        password = data.get('password')
        remembered = data.get('remembered')

        from django.contrib.auth import authenticate
        if not all([username,password]):
            return JsonResponse({'code':400,'errmsg':'缺少参数'})

        if re.match(r'1[3-9]\d{9}',username):
            User.USERNAME_FIELD = 'mobile'
        else:
            User.USERNAME_FIELD = 'username'

        user = authenticate(username = username,password = password)
        if user == None:
            return JsonResponse({'code':400,'errmsg':'用户名或密码错误'})

        # 记住账号密码
        if remembered:
            request.session.set_expiry(None)
        else:
            request.session.set_expiry(0)

        # session 状态保持
        from django.contrib.auth import login
        login(request,user)

        # 设置cookie
        response = JsonResponse({'code':0,'errmsg':'ok'})
        response.set_cookie('username',username,max_age = 3600 * 24 * 15)

        return response

# 退出登录
class LogoutView(View):
    def delete(self,request):
        logout(request)
        response = JsonResponse({'code':400,'errmsg':'ok'})
        response.delete_cookie('username')
        return response


# 用户中心管理权限逻辑
# from django.contrib.auth.mixins import LoginRequiredMixin

# 方法一 重写  LoginRequiredMixin 类的 dispatch 方法,缺点:只能用在用户中心,复用性差,如果要用在支付等其他地方,要重复写这段代码
# class LoginRequiredJSONMixin(LoginRequiredMixin):
#     def dispatch(self, request, *args, **kwargs):
#         if not request.user.is_authenticated:
#             return JsonResponse({'code':400,'errmsg':'未登录'})
#         return super().dispatch(request, *args, **kwargs)
# class CenterView(LoginRequiredJSONMixin,View):
#     def get(self,request):
#         return JsonResponse({'code':0,'errmsg':'ok'})

# 方法二 重写 LoginRequiredMixin 类的 handle_no_permission 方法
# class LoginRequiredJSONMixin(LoginRequiredMixin):
#     def handle_no_permission(self):
#         return JsonResponse({'code':400,'errmsg':'账号未登录'})
#
# class CenterView(LoginRequiredJSONMixin,View):
#     def get(self,request):
#         return JsonResponse({'code':0,'errmsg':'ok'})

# 方法三 在 utils 文件夹新建一个 view.py 文件,新建类 LoginRequiredJSONMixin,重写 LoginRequiredMixin 类中的 handle_no_permission 方法
# 所有需要验证用户登录权限的类都可以导入 LoginRequiredJSONMixin 进行权限管理
from utils.views import LoginRequiredJSONMixin

class CenterView(LoginRequiredJSONMixin,View):
    def get(self,request):
        info_data = {
            'username' : request.user.username,
            'email' : request.user.email,
            'mobile' : request.user.mobile,
            'email_active':request.user.email_active
        }
        print(info_data)
        return JsonResponse({'code':0,'errmsg':'ok','info_data':info_data})

class EmailView(LoginRequiredJSONMixin,View):
    def put(self,request):
        json_dict = json.loads(request.body)
        email = json_dict.get('email')
        if not email:
            return JsonResponse({'code':400,'errmsg':'缺少email数据'})
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$',email):
            return JsonResponse({'code':400,'errmsg':'email格式错误'})

        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            print(e)
            return JsonResponse({'code':400,'errmsg':'添加email失败'})

        # 发送认证邮件
        from django.core.mail import send_mail
        '''
        subject: 邮件标题  
        message：邮件内容
        from_email：发件人 发件人邮箱需要进行特殊设置
        recipient_list：收件人 [列表类型]
        
        要到setting.py配置邮箱相关信息
        '''
        email = request.user.email
        subject = '图灵商城激活邮件'
        from_email = '图灵商城<173126631@qq.com>'
        recipient_list = [email]
        # 发普通信息用 message ,发包含链接的信息用 html_message
        message = ""

        from apps.users.utils import generic_email_verify_token
        # 发送验证邮件
        token = generic_email_verify_token(user_id = request.user.id)
        verify_url = 'http://127.0.0.1:8080/success_verify_email.html?token=%s' % token
        html_message = '<p>尊敬的用户您好！</p>' \
                       '<p>感谢您使用图灵商城。</p>' \
                       '<p>您的邮箱为：%s 。请点击此链接激活您的邮箱：</p>' \
                       '<p><a href="%s">%s<a></p>' % (email, verify_url, verify_url)

        # 因为发送邮件也是属于堵塞代码 所以使用celery进行异步发送
        # send_mail(
        #     subject = subject,
        #     message = message,
        #     from_email=from_email,
        #     recipient_list = recipient_list,
        #     html_message = html_message
        # )

        # 使用celery进行邮件发送
        from celery_tasks.email.tasks import celery_send_email

        celery_send_email.delay(
            subject=subject,
            message=message,
            from_email=from_email,
            recipient_list=recipient_list,
            html_message=html_message
        )

        return JsonResponse({'code':0,'errmsg':'ok'})

# 邮箱状态验证

class EmailVerifyView(View):
    # 加密
    def put(self,request):
        parmas = request.GET
        token = parmas.get('token')
        if token is None:
            return JsonResponse({'code':400,'errmsg':'参数缺失'})

        # 解密
        from apps.users.utils import check_verify_token
        user_id = check_verify_token(token)
        if user_id is None:
            return JsonResponse({'code0':400,'errmsg':'参数错误'})
        user = User.objects.filter(id=user_id).first()
        user.email_active = True
        user.save()

        return JsonResponse({'code':0,'errmsg':'ok'})






















